# coding=utf-8
"""
    以 windows 服务方式运行该项目
    好处是可以配置开机自启动

    python curl_conversion_server.py install
    python curl_conversion_server.py start
    Windows 服务中, 将服务设置为开机自启动

"""
import sys

import win32serviceutil
import win32service
import win32event
import servicemanager
import socket
import threading

from run import run
from utils.do_log import c_log

# @Time    :  2024-09-19 17:29:01
# @Author  :  jiangtong
# @Email   :  gingerqgyy@outlook.com
# @Project :  test_curl_convert
# @File    :  curl_conversion_server

flask_port = 5000


class CurlConversionService(win32serviceutil.ServiceFramework):
    # 服务名称, 服务描述 :
    _svc_name_ = "Curl To Py Server"
    _svc_display_name_ = "Ginger Service For Curl To Py"
    _svc_description_ = "Ginger Server For Curl To Py"

    # 初始化服务 :
    def __init__(self, args):
        self.curl_conversion = None
        # 设置超时时间
        socket.setdefaulttimeout(60)
        # 创建一个服务框架对象
        win32serviceutil.ServiceFramework.__init__(self, args)
        # 创建事件对象: 用于在服务停止时接收信息
        self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
        self.is_alive = True

    # 停止服务, 当命令行中执行 python curl_conversion_server.py stop 时, 会执行这里的代码
    def SvcStop(self):
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        win32event.SetEvent(self.hWaitStop)
        self.is_alive = False

    # 服务启动, 当命令行执行 python curl_conversion_server.py start 时, 会执行这里的代码 , ( 开机自启动也会 )
    def SvcDoRun(self):
        self.is_alive = True
        servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE, servicemanager.PYS_SERVICE_STARTED, (self._svc_name_, ''))

        def flask_thread():
            try:
                c_log.info('服务启动')
                # 禁用多线程和调试模式
                self.curl_conversion = run(port=flask_port)
            except Exception as e:
                c_log.error(f'服务异常, {e}')
                servicemanager.LogErrorMsg(f"Error in flask_thread: {str(e)}")
                self.SvcStop()

        # 启动 Flask 服务线程
        flask_service_thread = threading.Thread(target=flask_thread)
        flask_service_thread.start()

        # 等待服务停止事件
        win32event.WaitForSingleObject(self.hWaitStop, win32event.INFINITE)

    def main(self):
        if self.is_alive:
            try:
                c_log.info('服务启动')
                run(port=flask_port)  # 检查这个端口是否被占用
            except OSError as e:
                servicemanager.LogErrorMsg(f"端口 {flask_port} 占用: {str(e)}")
                self.SvcStop()
                c_log.exception(f'服务遇到异常, {e}')


if __name__ == '__main__':
    pass
    # 发布为 windows 服务 :
    # """
    # 命令行参数数量为 1 个, 表示命令行就是命令本身时 :
    if len(sys.argv) == 1:
        # 初始化服务管理器 :
        servicemanager.Initialize()
        # 准备将 HttpServerService 作为单个服务进行托管 :
        servicemanager.PrepareToHostSingle(CurlConversionService)
        # 启动服务控制调度器, 以便可以接收和处理来自其他进程的服务控制请求
        servicemanager.StartServiceCtrlDispatcher()
    else:
        win32serviceutil.HandleCommandLine(CurlConversionService)
    # """
